﻿//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#region << 版 本 注 释 >>

/*----------------------------------------------------------------
* 类 名 称 ：Gate
* 类 描 述 ：
* 作    者 ：henrychang
* 创建时间 ：2019/1/22 15:31:54
*******************************************************************
* Copyright @ henrychang 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;

namespace TouchFish.PureMVC
{
    public class FacadeKey
    {
        public const int UIFacadeKey = 1;
    }

    public class Facade : IFacade
    {
        protected IController controller;
        protected IModel model;
        protected IView view;
        protected int multitonKey = 0;

        protected Facade(int key)
        {
            IFacade facade;
            if (instanceMap.TryGetValue(key, out facade) && multitonKey > 0)
                throw new Exception(ERROR_MSG + "  " + key);
            InitializeNotifier(key);
            instanceMap.TryAdd(key, this);
            InitializeFacade();
        }

        public virtual void InitializeNotifier(int key)
        {
            multitonKey = key;
        }

        protected virtual void InitializeFacade()
        {
            InitializeModel();
            InitializeController();
            InitializeView();
        }

        protected virtual void InitializeController()
        {
            controller = Controller.GetInstance(multitonKey);
        }

        protected virtual void InitializeModel()
        {
            model = Model.GetInstance(multitonKey);
        }

        protected virtual void InitializeView()
        {
            view = View.GetInstance(multitonKey);
        }

        public virtual void RegisterCommand(int notificationId, Func<ICommand> commandClassRef)
        {
            controller.RegisterCommand(notificationId, commandClassRef);
        }

        public virtual void RemoveCommand(int notificationId)
        {
            controller.RemoveCommand(notificationId);
        }

        public virtual bool HasCommand(int notificationId)
        {
            return controller.HasCommand(notificationId);
        }

        public virtual void RegisterProxy(IModelProxy proxy)
        {
            model.RegisterProxy(proxy);
        }

        public virtual IModelProxy RetrieveProxy(int proxyId)
        {
            return model.RetrieveProxy(proxyId);
        }

        public virtual IModelProxy RemoveProxy(int proxyId)
        {
            return model.RemoveProxy(proxyId);
        }

        public virtual bool HasProxy(int proxyId)
        {
            return model.HasProxy(proxyId);
        }

        public virtual void RegisterMediator(IViewMediator mediator)
        {
            view.RegisterMediator(mediator);
        }

        public virtual IViewMediator RetrieveMediator(int mediatorId)
        {
            return view.RetrieveMediator(mediatorId);
        }

        public virtual IViewMediator RemoveMediator(int mediatorId)
        {
            return view.RemoveMediator(mediatorId);
        }

        public virtual bool HasMediator(int mediatorId)
        {
            return view.HasMediator(mediatorId);
        }

        public virtual void SendNotification(int notificationId, object body = null, string type = null)
        {
            NotifyObservers(new Notification(notificationId, body, type));
        }

        public virtual void NotifyObservers(INotification notification)
        {
            view.NotifyObservers(notification);
        }

        #region Static

        // TODO:可进行自定义Facade的扩展,Controller View Model
        //public static IFacade GetInstance(int key, Func<IFacade> func)
        //{
        //    IFacade facade;
        //    if (!instanceMap.TryGetValue(key, out facade))
        //    {
        //        facade = func();
        //    }
        //    return facade;
        //}

        public static IFacade GetInstance(int key)
        {
            IFacade facade;
            if (!instanceMap.TryGetValue(key, out facade))
            {
                facade = new Facade(key);
            }
            return facade;
        }

        public static bool HasCore(int key)
        {
            return instanceMap.ContainsKey(key);
        }

        public static void RemoveCore(int key)
        {
            if (!instanceMap.ContainsKey(key)) return;
            Model.RemoveModel(key);
            View.RemoveView(key);
            Controller.RemoveController(key);
            instanceMap.Remove(key);
        }

        protected static Dictionary<int, IFacade> instanceMap = new Dictionary<int, IFacade>();

        protected const string ERROR_MSG = "已经创建过 Facade Key值的实例";

        #endregion Static
    }
}